// 性能监控工具

interface PerformanceMetric {
  name: string;
  value: number;
  timestamp: number;
  tags?: Record<string, string>;
}

interface PerformanceConfig {
  enabled: boolean;
  sampleRate: number;
  maxMetrics: number;
  reportInterval: number;
}

class PerformanceMonitor {
  private config: PerformanceConfig;
  private metrics: PerformanceMetric[] = [];
  private startTime = performance.now();

  constructor(config: Partial<PerformanceConfig> = {}) {
    this.config = {
      enabled: true,
      sampleRate: 1,
      maxMetrics: 1000,
      reportInterval: 30000, // 30 seconds
      ...config,
    };

    if (this.config.enabled) {
      this.init();
    }
  }

  private init(): void {
    // 监控页面加载性能
    window.addEventListener('load', () => {
      this.recordPageLoadMetrics();
    });

    // 定期上报性能指标
    setInterval(() => {
      this.reportMetrics();
    }, this.config.reportInterval);

    // 监控资源加载
    this.observeResourceTiming();
  }

  private recordPageLoadMetrics(): void {
    if (!window.performance) return;

    const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
    const paint = performance.getEntriesByType('paint');

    this.recordMetric('page_load_time', navigation.loadEventEnd - navigation.startTime);
    this.recordMetric('dom_content_loaded', navigation.domContentLoadedEventEnd - navigation.startTime);
    this.recordMetric('first_paint', paint.find(p => p.name === 'first-paint')?.startTime || 0);
    this.recordMetric('first_contentful_paint', paint.find(p => p.name === 'first-contentful-paint')?.startTime || 0);
  }

  private observeResourceTiming(): void {
    if (!window.PerformanceObserver) return;

    const observer = new PerformanceObserver((list) => {
      const entries = list.getEntries();
      entries.forEach((entry) => {
        if (entry.duration > 1000) { // 只记录超过1秒的资源
          this.recordMetric('slow_resource', entry.duration, {
            resource_type: entry.initiatorType,
            resource_name: entry.name,
          });
        }
      });
    });

    observer.observe({ entryTypes: ['resource'] });
  }

  recordMetric(name: string, value: number, tags?: Record<string, string>): void {
    if (!this.config.enabled || Math.random() > this.config.sampleRate) {
      return;
    }

    const metric: PerformanceMetric = {
      name,
      value,
      timestamp: Date.now(),
      tags,
    };

    this.metrics.push(metric);

    // 防止内存泄漏
    if (this.metrics.length > this.config.maxMetrics) {
      this.metrics = this.metrics.slice(-this.config.maxMetrics);
    }

    // 实时告警
    this.checkThreshold(metric);
  }

  private checkThreshold(metric: PerformanceMetric): void {
    const thresholds: Record<string, number> = {
      page_load_time: 3000,
      api_response_time: 2000,
      render_time: 100,
      slow_resource: 5000,
    };

    const threshold = thresholds[metric.name];
    if (threshold && metric.value > threshold) {
      console.warn(`Performance warning: ${metric.name} exceeded threshold`, {
        value: metric.value,
        threshold,
        tags: metric.tags,
      });

      // 这里可以添加告警逻辑
      // this.sendAlert(metric);
    }
  }

  private reportMetrics(): void {
    if (this.metrics.length === 0) return;

    const metricsToReport = [...this.metrics];
    this.metrics = [];

    // 这里可以上报到监控系统
    console.log('Performance metrics:', metricsToReport);

    // 示例：计算平均值
    const averages = this.calculateAverages(metricsToReport);
    console.log('Performance averages:', averages);
  }

  private calculateAverages(metrics: PerformanceMetric[]): Record<string, number> {
    const groups: Record<string, number[]> = {};

    metrics.forEach(metric => {
      if (!groups[metric.name]) {
        groups[metric.name] = [];
      }
      groups[metric.name].push(metric.value);
    });

    const averages: Record<string, number> = {};
    Object.keys(groups).forEach(name => {
      const values = groups[name];
      averages[name] = values.reduce((sum, val) => sum + val, 0) / values.length;
    });

    return averages;
  }

  // 工具方法
  time<T>(name: string, fn: () => T, tags?: Record<string, string>): T {
    const start = performance.now();
    const result = fn();
    const duration = performance.now() - start;

    this.recordMetric(name, duration, tags);
    return result;
  }

  async timeAsync<T>(name: string, fn: () => Promise<T>, tags?: Record<string, string>): Promise<T> {
    const start = performance.now();
    const result = await fn();
    const duration = performance.now() - start;

    this.recordMetric(name, duration, tags);
    return result;
  }

  getMetrics(): PerformanceMetric[] {
    return [...this.metrics];
  }

  clearMetrics(): void {
    this.metrics = [];
  }

  getUptime(): number {
    return performance.now() - this.startTime;
  }
}

// 全局性能监控实例
export const performanceMonitor = new PerformanceMonitor({
  enabled: process.env.NODE_ENV === 'production',
  sampleRate: 0.1, // 10% 采样率
  maxMetrics: 100,
  reportInterval: 60000, // 1分钟
});

// 性能 Hook
export function usePerformance() {
  const [metrics, setMetrics] = React.useState<PerformanceMetric[]>([]);
  const [uptime, setUptime] = React.useState(0);

  React.useEffect(() => {
    const interval = setInterval(() => {
      setMetrics(performanceMonitor.getMetrics());
      setUptime(performanceMonitor.getUptime());
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return {
    metrics,
    uptime,
    recordMetric: performanceMonitor.recordMetric.bind(performanceMonitor),
    clearMetrics: performanceMonitor.clearMetrics.bind(performanceMonitor),
  };
}

// 组件性能监控 Hook
export function useComponentPerformance(componentName: string) {
  const renderCount = React.useRef(0);
  const renderTime = React.useRef(0);
  const lastRenderTime = React.useRef(0);

  React.useEffect(() => {
    renderCount.current += 1;
    const now = performance.now();

    if (lastRenderTime.current > 0) {
      const timeSinceLastRender = now - lastRenderTime.current;
      renderTime.current += timeSinceLastRender;

      performanceMonitor.recordMetric('component_render', timeSinceLastRender, {
        component_name: componentName,
        render_count: renderCount.current.toString(),
      });
    }

    lastRenderTime.current = now;
  });

  React.useEffect(() => {
    return () => {
      // 组件卸载时记录总渲染时间
      if (renderCount.current > 0) {
        performanceMonitor.recordMetric('component_total_render_time', renderTime.current, {
          component_name: componentName,
          total_renders: renderCount.current.toString(),
        });
      }
    };
  }, [componentName]);

  return {
    renderCount: renderCount.current,
    renderTime: renderTime.current,
  };
}

// API 性能监控 Hook
export function useApiPerformance() {
  const recordApiCall = React.useCallback((url: string, duration: number, method: string = 'GET') => {
    performanceMonitor.recordMetric('api_response_time', duration, {
      url,
      method,
    });
  }, []);

  const recordApiError = React.useCallback((url: string, error: Error, method: string = 'GET') => {
    performanceMonitor.recordMetric('api_error', 1, {
      url,
      method,
      error_type: error.name,
    });
  }, []);

  return {
    recordApiCall,
    recordApiError,
  };
}

// 资源预加载
export function preloadResources(urls: string[]): void {
  urls.forEach(url => {
    const link = document.createElement('link');
    link.rel = 'preload';
    link.as = url.endsWith('.js') ? 'script' :
               url.endsWith('.css') ? 'style' :
               url.endsWith('.png') || url.endsWith('.jpg') || url.endsWith('.gif') ? 'image' : 'fetch';
    link.href = url;
    document.head.appendChild(link);
  });
}

// 预连接到指定域名
export function preconnect(host: string): void {
  const link = document.createElement('link');
  link.rel = 'preconnect';
  link.href = host;
  document.head.appendChild(link);
}

// DNS 预解析
export function dnsPrefetch(host: string): void {
  const link = document.createElement('link');
  link.rel = 'dns-prefetch';
  link.href = host;
  document.head.appendChild(link);
}